import io
import string
import random

import logging

from config.fastdfs.config import FASTDFS_SERVER_DOMAIN

logger = logging.getLogger(__name__)

from django.contrib.auth.models import User
from django.http import HttpResponse,JsonResponse
from rest_framework import status
from rest_framework.response import Response

from utils.permission import wrap_premission, ActiveUserPersmission, TeacherPermission
from .models import UserDetail
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ReadOnlyModelViewSet, ModelViewSet

from config.dbs.redis_rev import LOGIN_KEY_TEMPLATE, EXPIRE_TIME,LOGIN_KEY_TEMPLATE1
from users.serializers import UserSerializer, CheickUserSerializer, UserDetailSerializer, UpdataSerializer, \
    UpdateUserAvaterSerializer
from utils.ronglianyun import Message
# from utils.verifyUtil import ImageVerify

#
# class Mage_verufy(View):
#     def get(self,request,uuid):
#         '''
#         返回图片验证码
#         @param request:请求对象
#         @param uuid:客户端唯一识别码
#         @return:
#         '''
#         #实例化验证码类
#         imgVerify = ImageVerify()
#         img,code = imgVerify.verify_code()
#
#         #将图片数据返回给客户端，并且无需持久化
#         #生成字节数据
#         img_bytes = io.BytesIO()
#         img.save(img_bytes,format('PNG'))
#         image_bytes = img_bytes.getvalue()#获取图片字节数据
#
#         #如何保存 uuid:AW2j key-value 临时保存如redis
#         cache = get_redis_connection(alias='verify_code')
#         cache.set(LOGIN_KEY_TEMPLATE % uuid , code ,EXPIRE_TIME)
#
#         return HttpResponse(image_bytes,content_type='image/png')

class GetcodeView(View):
    def get(self,request):
        print(request.GET.get('phone'))
        print(111)
        #创建验证码
        source = string.digits
        res = ''.join(random.sample(source,6))
        #导入容联云短信验证
        message = Message().send_message('1',request.GET.get('phone'),(res,'5'))
        #判断验证码返回是否成功
        print(message,1111)
        if message == 0:
            cache = get_redis_connection(alias='verify_code1')
            cache.set(LOGIN_KEY_TEMPLATE1 % 1,res,EXPIRE_TIME)
            #将验证码返回数据库
        else:
            return JsonResponse({
                'status':'404',
                'msg':'验证码返回失败'
            })
        return JsonResponse({
            'status':'202',
            'msg':'验证码返回成功'
        })

#ReadOnlyModelViewSet为什么要使用这个模型呢，因为是要展示数据，并不提供创建修改删除的功能，
# ReadOnlyModelViewSet正好没有继承这三个的模型所以使用它
class UserViewSet(ReadOnlyModelViewSet):
    queryset = User.objects.filter(is_active=1)
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]
    @wrap_premission(TeacherPermission)
    def list(self, request, *args, **kwargs):
        return ModelViewSet.list(self, request, *args, **kwargs)
    @wrap_premission(ActiveUserPersmission)
    def retrieve(self, request, *args, **kwargs):
        return ModelViewSet.retrieve(self, request, *args, **kwargs)

    def get_serializer(self, *args, **kwargs):
        if self.action == 'updata':
            return UpdataSerializer(*args,**kwargs)
        return self.serializer_class(*args,**kwargs)

    @action(methods=["put"],detail=True)
    def updata(self,request,pk):
        try:
            user = self.get_queryset().get(id=pk)
        except:
            Response(status = status.HTTP_404_NOT_FOUND)
        serializer = self.get_serializer(data = request.data)
        serializer.is_valid(raise_exception=True)
        password = request.data['password']
        new_password = request.data['new_password']
        print(password,new_password)
        if user.check_password(password):#check_password是django自带的一个比较纯文本密码和数据库中哈希后的密码的验证函数
            user.set_password(new_password)#set_password即是通过加密来保存的一个密码
        else :
            return Response(status=status.HTTP_400_BAD_REQUEST)
        # 保存邮箱和用户名
        user.email = request.data['new_email']
        user.first_name = request.data['first_name']
        user.save()
        return Response({
            'status': status.HTTP_201_CREATED,
            'msg': '用户信息修改成功'
        })
from fdfs_client.client import Fdfs_client, get_tracker_conf

tracker_path = get_tracker_conf('utils/fastdfs/client.conf')
client = Fdfs_client(tracker_path)
class UpdateUserAvater(ModelViewSet):
    queryset = UserDetail.objects.all()
    serializer_class = UpdateUserAvaterSerializer
    permission_classes = [IsAuthenticated]

    def update(self, request, pk):
        try:
            user = User.objects.get(id = pk)
        except User.DoesNotExist:
            return Response(status = status.HTTP_404_NOT_FOUND)
        print(request.data)
        # 如果是用后台测试,那么就是avatar = request.FILES.get('avatar')
        #如果是前端传尽力的那么就是用file为key做字典传值
        avatar = request.FILES.get('file')
        # avatar = request.FILES.get('avatar')
        print(avatar)
        if not avatar or avatar.content_type not in ('image/jpeg', 'image/png', 'image/gif','image/jpg'):
            return Response({
                'status':status.HTTP_404_NOT_FOUND,
                'msg':'图片格式不正确'
            })
        try:
            images_ext_name = avatar.name.split('.')[-1]
        except Exception as e:
            logger.info('图片上传出现异常%s'%e)
            images_ext_name = 'png'
        #通过字节流上传图片
        try:
            upload_res = client.upload_by_buffer(avatar.read(),file_ext_name=images_ext_name)
        except Exception as e :
            logger.error('图片上传出现异常：%s'%e)
            return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            if upload_res.get('Status')!='Upload successed.':
                logger.warning('图片上传失败')
                return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            image_name = upload_res.get('Remote file_id').decode()
            image_url = FASTDFS_SERVER_DOMAIN + image_name
            # image_url = f'{"http://"}'+image_url


            # 判断是否有详情表数据
            if hasattr(user, 'userdetail'):
                # 如果有，则修改头像字段，保存图片信息
                user_detail = user.userdetail  # 得到当前操作用户的用户详情模型对象
                print(user_detail)
                print(UserDetail.objects.filter(id=pk))
                user_detail.avatar = image_url
                user_detail.save()
            else:
                # 如果没有，则创建详情，保存图片信息
                UserDetail.objects.create(avatar=image_url, user=user)
            # 返回图片地址
            print(image_url)
            return Response({'data': image_url})


class UpdateUserViewSet(ModelViewSet):
    queryset = User.objects.filter(is_active=1)
    serializer_class = CheickUserSerializer
    permission_classes = [IsAuthenticated]

class CheickdatielViewSet(ModelViewSet):
    queryset = UserDetail.objects.all()
    serializer_class = UserDetailSerializer
    permission_classes = [IsAuthenticated]
    @action(methods=['get'],detail=True)
    def get_userdateil_data(self,request,pk):
        try:
            userdateil = UserDetail.objects.get(user_id=pk)
        except:
            return Response({
                'status':status.HTTP_404_NOT_FOUND,
                'msg':'没有用户详情数据'
            })
        serializer = UserDetailSerializer(userdateil)
        print(serializer.data)
        #返回数据要用Response
        return Response({
            'status':status.HTTP_202_ACCEPTED,
            'data':serializer.data
        })
    # 这个是自定义的用户详情数据修改
    @action(methods=['put'],detail=True)
    def updata_userdateil_data(self,request,pk):
        try:
            userdateil = UserDetail.objects.get(user_id=pk)
        except:
            #此处应该直接使用数据库创建
            print(request.data)
            user_Dateil = UserDetail.objects.create(**request.data)
            serializer = UserDetailSerializer(user_Dateil)
            return Response(serializer.data)
        #save里面有两个方法，一个create一个updata serializer里有一个参数就是create两个就是updata
        #前端dirthday那里的日期，不能用2001-12-25格式的原因是模型哪里datetimefile是一定要加时分秒的，DateField应该使用这个
        serializer = UserDetailSerializer(instance=userdateil ,data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({
            'status':status.HTTP_202_ACCEPTED,
            'data':serializer.data
        })





